        TITL DAI FIRMWARE 0EC16-0EE08  V1.0  Rev.1
        ORG   :EC16
*
*
*
**************************
* RUN basicfunction PEEK *
**************************
*
* Returns the contents of a memory location
* with an address given as INT argument.
*
RPEEK   CALL  :E6F8     Get addr in HL
        MOV   A,M       Get its contents
        JMP   :EB7C     Move it into MACC
*
************************
* RUN basicfunction PI *
************************
*
* Returns a value of 3.14159.
*
RPI     LXI   H,:D0F5   Addr FPT (PI)
        RST   4         FPT (PI) into MACC
        DATA  :0C
        RET
*
*********************
* DATA - (not used) *
*********************
*
L0E252  DATA  :02       FPT (PI)
        DATA  :C9
        DATA  :0F
        DATA  :DB
*
*************************
* RUN basicfunction RND *
*************************
*
* Returns a random or pseudo-random number.
* If argument > 0: Returns a pseudo-random number
*                  in the range 0 <= R < argument.
* If argument = 0: Returns a hardware random number
*                  0 < R < 1.
* If argument < 0: Number replaces the kernel for
*                  calculating further pseudo-
*                  random numbers.
*
RRND    CALL  :EC8A     Test if arg is 0
        JZ    :E40C     Then hardware random
        LXI   H,:012D   Addr random number kernel
        JP    :EC35     If pseudo random number
        RST   4         Copy MACC to kernel
        DATA  :0F
        XCHG
        LXI   H,:0129   Addr scratch area WORKE
        RST   4         Copy MACC to WORKE
        DATA  :0F
        PUSH  H         Saveaddr WORKE
        XCHG
        PUSH  H         Save addr RNUM
        MVI   M,:01     Limit range 1-2
        RST   4         Copy last nr from RNUM
        DATA  :0C       into MACC
        MVI   D,:05
RRD10   LXI   H,:C6A8   Addr RNDA
        RST   4         Multiply RO*RNDA
        DATA  :54
        LXI   H,:C6AC   Addr RNDB
        RST   4         Add RNDB to RO*RNDA
        DATA  :4E
        NOP
        NOP
        NOP
        NOP
        NOP
        LXI   H,:D0FD   Addr AND mask
        RST   4         IAND: pick out mantissa
        DATA  :63
        LXI   H,:C6B0   Addr OR mask
        RST   4         IOR: set mantissa top
        DATA  :66       bit, + range 1-2
        DCR   D
        JNZ   :EC44     Again if D<>0
        POP   H         Get addr RNUM
        RST   4         Copy MACC to RNUM
        DATA  :0F
        LXI   H,:D0F1   Addr FPT (-1)
        RST   4         Add -1 to MACC (range
        DATA  :00       0-1)
        POP   H         Get addr WORKE
        RST   4         Frig range: multiply
        DATA  :06       MACC*(WORKE)
        RET
*
***************************
* part of RUN TALK (CD64) *
***************************
*
* Entry: Z=1: Code = 0C (delay).
*        Z=0: Code = 0D (ML call)
*
MPT46   MOV   E,M       )
        INX   H         ) Wait-time/ML address
        MOV   D,M       ) in HL
        INX   H         )
        XCHG            )
        CZ    :DACC     If to be waited
        CNZ   :C8A9     Else: Run ML routine
        JMP   :CD67     Return: Handle next code
*
*************************
* RUN basicfunction SGN *
*************************
*
* Takes a FPT value and returns:
*               +1  if value is positive.
*                0  if value is zero.
*               -1  if value is negative.
*
RSGN    CALL  :EC8A     Test if variable is zero
        RZ              Then ready
        LXI   H,:D0F1   Addr FPT(-1)
        RST   4         Copy -1 into MACC
        DATA  :0C
        JM    :EC89     Ready if already negative
        RST   4         Else change sign MACC
        DATA  :1B       (make MACC +1)
L0E257  RET
*
***********************
* TEST A FPT VARIABLE *
***********************
*
* Entry: Variable in MACC.
* Exit:  Z=1: Variable is zero.
*        Z=0: Other flags set on exponent byte
*             of variable.
*        ABCDEHL preserved.
*
FTEST   PUSH  B
        PUSH  D
        PUSH  PSW
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        MOV   E,A       Exp byte in E
        ORA   B         )
        ORA   C         ) Check if nr is zero
        ORA   D         )
        JZ    :EC98     Then quit
        MOV   A,E       Get exp byte
        ORA   A         Set flags on it
FTS10   POP   D
        MOV   A,D
        POP   D
        POP   B
        RET
*
**************************
* RUN basicfunction SCRN *
**************************
*
RSCRN   CALL  :E5F3     Eval given coord
        PUSH  B
        MOV   C,A       Y-coord in C
        RST   5         Ask colour of dot on screen
        DATA  :27       + size graphics screen
        POP   B
        JC    :E602     Evt run screen error
        JMP   :EB7C     Contents screen loc in MACC
*
*
*  ==============
*** LIST HANDLER ***
*  ==============
*
* This module lists a program from the textbuffer
* onto the screen (or into other required direction)
*
***********************
* LIST A PROGRAM LINE *
***********************
*
* Entry: BC: Points to start of textline.
* Exit:  BC: Points to start of next line.
*        DEHL preserved, AF corrupted.
*
SLINE   PUSH  D
        PUSH  H
        INX   B         Pnts to line nr
        CALL  :EFAE     List line nr
        MVI   A,:08
        CALL  :DB2A     Cursor to tab 8
L0E262  CALL  :ECCC     List statement
        LDAX  B         Get next byte
        ORA   A
        JP    :ECC5     If no more statements
        CALL  :EFF5     Else: print ':'
        DATA  :3A
        JMP   :ECB6     List next statement
L0E263  CALL  :EFF5     print car.ret
        DATA  :0D
        POP   H
        POP   D
        RET
*
********************
* LIST A STATEMENT *
********************
*
* Based on the token in the textbuffer, a particular
* statement will be printed.
* At first, the Basiccommand will be printed. The
* pointers to the particular strings are in a table
* starting at CD8B. The base for the table is CC08;
* the offset is calculated by TOKEN *3.
*
* The databyte after the stringaddress pointer
* indicates which list-routine has to be used for
* the rest of the statement. This byte is a offset
* for table ECF8.
*
* Entry: BC: Points to token.
* Exit:  BC: Points to next statement.
*        AFDEHL corrupted.
*        On stack: Returnaddress from this sub-
*        routine.
*
SCOM    LDAX  B         Get token
        INX   B         Update pointer
        MOV   E,A       token in E
        MVI   D,:00
        LXI   H,:CC08   Startaddr stringtable
        DAD   D         ) Add 3* token
        DAD   D         )
        DAD   D         )
        MOV   E,M       Get lobyte stringaddr
        INX   H
        MOV   D,M       Get hibyte stringaddr
        INX   H         Point to data after addr
        XCHG            Stringaddr in HL
        MOV   A,M       Get length byte of string
        ORA   A         Length=0?
        CALL  :DB32     List Basiccmd string
        LDAX  D         Get data byte after string-
 REM address
        JZ    :ECEA     If length string =0
        CPI   :00
        CNZ   :CE6B     Print space if byte after
 REM stringaddr <>0
SCM10   LDAX  D         Get data byte (= offset)
        ADD   A         Offset *2
        MOV   E,A       in E
        MVI   D,:00
        LXI   H,:ECF8   Startaddr table Listroutines
        DAD   D         Add offset
        MOV   E,M       Get addr in DE
        INX   H
        MOV   D,M
        XCHG            Addr routine in HL
        PCHL            Go to this adress
*
***********************************
* POINTERS LIST HANDLING ROUTINES *
***********************************
*
* Table with addresses of listroutines for the
* part of a statement after a token.
*
* Startaddress table is ECF8. The offset (given
* between brackets) is identical to the data
* byte after the addresses in the table on CD8B.
*
L0E355  DBL   :ED3A     (00)  nothing more
        DBL   :ED41     (01)  linenr
        DBL   :ED3B     (02)  linenr linenr
 REM       (not used)
        DBL   :ED44     (03)  unquoted string
        DBL   :ED4D     (04)  E (E=expr)
        DBL   :ED47     (05)  E,E
        DBL   :ED56     (06)  E E
        DBL   :ED62     (07)  E,E E
        DBL   :ED5C     (08)  E,E E,E E
        DBL   :ED50     (09)  E E E E
        DBL   :ED6B     (0A)  E
        DBL   :ED7A     (0B)  liner-linenr
        DBL   :ED84     (0C)  sound
        DBL   :ED9B     (0D)  noise
        DBL   :EDA4     (0E)  envelope
        DBL   :EDC1     (0F)  mode
        DBL   :EDD9     (10)  input <string>
        DBL   :EDE0     (11)  input/read/dim
        DBL   :EDF0     (12)  (not used [*])
        DBL   :EDFF     (13)  let
        DBL   :EE09     (14)  if then <E>
        DBL   :EE1A     (15)  if goto <linenr>
        DBL   :EE25     (16)  if then <linenr>
        DBL   :EE30     (17)  for to step
        DBL   :EE4F     (18)  next
        DBL   :EE52     (19)  print
        DBL   :EE66     (1A)  on goto
        DBL   :EE71     (1B)  on gosub
        DBL   :EE87     (1C)  callm
        DBL   :EE94     (1D)  (not used [*])
        DBL   :D89E     (1E)  savea/loada
*
* The vectors marked with [*] are no pointers to
* LIST routines.
*
        DATA  :FF
        DATA  :FF
        DATA  :FF
        DATA  :FF
*
*******************************
* LIST NO FURTHER EXPRESSIONS *
*******************************
*
SCN1    RET
*
***************************
* LIST 1 OR 2 LINENUMBERS *
***************************
*
* SCN2: List 1 line number.
* SCN3: List 2 line numbers, separated by space.
*       (This last entry is not used).
*
* Exit: BC updated, DE preserved, AFHL corrupted.
*
SCN3    CALL  :EFAE     List linenr
        CALL  :CE6B     Print space
SCN2    JMP   :EFAE     List linenr
*
************************
* LIST UNQUOTED STRING *
************************
*
SCN5    JMP   :EFED     List unquoted string
*
**********************
* LIST <EXPR>,<EXPR> *
**********************
*
* Exit: BC updated, DE preserved, AFHL corrupted.
*
SCN7    CALL  :EEA2     List <expr>
SCOEX   CALL  :CE70     Print ','
SCN6    JMP   :EEA2     List <expr>
*
************************************
* LIST <EXPR> <EXPR> <EXPR> <EXPR> *
************************************
*
* Exit: BC updated, DE preserved, AFHL corrupted.
*
SCN11   CALL  :EFFC     List <expr>; print space
S3EXP   CALL  :EFFC     Idem
SCN8    CALL  :EFFC     Idem
        JMP   :EEA2     List <expr>
*
*******************************************
* LIST <EXPR>,<EXPR> <EXPR>,<EXPR> <EXPR> *
*******************************************
*
* Exit: BC updated, DE preserved, AFHL corrupted.
*
SCN10   CALL  :ED47     List <expr>,<expr>
        CALL  :CE6B     Print space
SCN9    CALL  :ED47     List <expr>,<expr>
SCSEX   CALL  :CE6B     Print space
L0E343  JMP   :EEA2     List <expr>
*
*******************************
* LIST <EXPR>,<EXPR>(,<EXPR>) *
*******************************
*
SCN12   CALL  :ED47     List <expr>,<expr>
S1210   LDAX  B         Get next byte
        CPI   :FF       Terminator?
        INX   B
        RZ              Then abort
        DCX   B
        CALL  :CE70     Print ','
        JMP   :EEA2     List <expr>
*
**************************
* LIST <LINENR>-<LINENR> *
**************************
*
* Exit: BC updated, DE preserved, AFHL corrupted.
*
SCN13   CALL  :EFAE     List linenr
        CALL  :EFF5     Print '-'
        DATA  :2D
        JMP   :EFAE     List linenr
*
*********************************
* LIST EXPRESSION AFTER 'SOUND' *
*********************************
*
* Exit: BC updated, AFHL corrupted.
*       DE: preserved if ON, corrupted if OFF.
*
SCN14   LDAX  B         Get byte
        CPI   :FF       OFF sign?
        CNZ   :EFFC     If not: List <expr>, print
 REM space
        LDAX  B         Get next byte
        CPI   :FF       OFF sign?
        JNZ   :ED50     If not: List <expr> <expr>
 REM <expr> <expr>; abort
S1410   CALL  :CE78     Else: print 'OFF'
        DBL   :ED97
        INX   B
        RET
*
* DATA:
*
L0E354  DATA  :03
        DATA  :4F       O
        DATA  :46       F
        DATA  :46       F
*
*********************************
* LIST EXPRESSION AFTER 'NOISE' *
*********************************
*
* Exit: BC updated, E preserved, AFDHL corrupted.
*
SC14A   LDAX  B         Get 1st byte NCB
        CPI   :FF       OFF sign?
        JZ    :ED90     Then print 'OFF', abort
        JMP   :ED56     Else: List <expr> <expr>
*
************************************
* LIST EXPRESSION AFTER 'ENVELOPE' *
************************************
*
* Exit: BC updated, E preserved, AFDHL corrupted.
*
SCN15   CALL  :EFFC     List <expr>, print
 REM space
        LDAX  B         Get length of expr
        INX   B
        MOV   D,A       into D
S1510   DCR   D
        JM    :EDB8     If ready
        CALL  :ED47     List <V>,<T>
        CALL  :EFF5     Print ';'
        DATA  :3B
        JMP   :EDAA     Next <V>,<T>
S1520   LDAX  B         Get last byte of expr
        INX   B
        CPI   :FF       Terminator?
        RZ              Then abort
        DCX   B
        JMP   :EEA2     List <expr>
*
********************************
* LIST EXPRESSION AFTER 'MODE' *
********************************
*
SCN16   LDAX  B         Get mode byte
        INX   B
        MVI   D,:30
        ORA   A         Mode 0 (FF) ?
        JM    :EDD4     Then print '0'
        RAR             CY=1 if A-mode
RSA10   INR   A
        PUSH  PSW
        ADD   D         Convert to ASCII
        CALL  :DD60     Print modenr
        POP   PSW
        CMC
        MVI   D,:41     Prepare print 'A'
S1610   MOV   A,D
        CNC   :DD60     Print 'A' if A-mode
        RET
*
**********************************************
* LIST EXPRESSION AFTER 'INPUT'-'READ'-'DIM' *
**********************************************
*
* Input with string:
 REM
SCN17   CALL  :EEA2     List string
        CALL  :EFF5     Print ';'
        DATA  :3B
 REM
* Rest:
 REM
SCN18   LDAX  B         Get nr of variables
        INX   B
        MOV   D,A       into D
S1810   PUSH  D
        CALL  :EEFC     List variable reference
        POP   D
        DCR   D         Decr nr of variables
        RZ              Abort if ready
        CALL  :CE70     Print ','
        JMP   :EDE3     List next variable
*
****************************************
* part of RUN 'DIM': CALC. REQD. SPACE *
****************************************
*
RDM40   JNZ   :DE8F     If length element <= 254:
 REM then HL=HL*A
        MOV   A,H       Else:
        ORA   A         Set flags on hibyte
        MOV   H,L
        MVI   L,:00
        RZ              Abort if H=0
        STC             Else: CY=1, L into H
        RET
*
************************
* RUBBISH - (not used) *
************************
*
L0E352  DATA  :CE
        DATA  :C3
        DATA  :F4
        DATA  :ED
*
*******************************
* LIST EXPRESSION AFTER 'LET' *
*******************************
*
* Entry: BC: Points to assign statement.
* Exit:  BC updated, AFDEHL corrupted.
*
SCN20   CALL  :EEFC     List lefthand variable
 REM reference
        CALL  :EFF5     Print '='
        DATA  :3D
        JMP   :EEA2     List righthand expr
*
        END
